﻿using System;

namespace dk.Helper.Base.Core
{
    public class Attack : IAttack
    {
        private readonly double distance;
        private DateTime end;
        private DateTime start;
        private int unitSpeed;

        /// <summary>
        /// Initializes a new instance of the <see cref="T:System.Object"/> class.
        /// </summary>
        /// <param name="from">From Village.</param>
        /// <param name="to">To Village.</param>
        /// <param name="unitSpeed">The unit speed.</param>
        public Attack(IVillage from, IVillage to, int unitSpeed)
        {
            distance = from.GetDistanceTo(to);
            end = DateTime.Now + new TimeSpan(1, 0, 0, 0);
            UnitSpeed = unitSpeed;
            From = from;
            To = to;
        }

        #region IAttack Members

        /// <summary>
        /// Gets from.
        /// </summary>
        public IVillage From { get; private set; }

        /// <summary>
        /// Gets to.
        /// </summary>
        public IVillage To { get; private set; }

        /// <summary>
        /// Gets or sets the unit speed.
        /// </summary>
        /// <value>
        /// The unit speed.
        /// </value>
        public int UnitSpeed
        {
            get { return unitSpeed; }
            set
            {
                if (unitSpeed != value)
                {
                    unitSpeed = value;
                    Duration = new TimeSpan(0, 0, 0, Convert.ToInt32(distance*unitSpeed*60));
                    start = end - Duration;
                    OnChanged(new EventArgs());
                }
            }
        }

        /// <summary>
        /// Gets or sets the start.
        /// </summary>
        /// <value>
        /// The start.
        /// </value>
        public DateTime Start
        {
            get { return start; }
            set
            {
                if (start != value)
                {
                    start = value;
                    end = start + Duration;
                }
            }
        }

        /// <summary>
        /// Gets or sets the end.
        /// </summary>
        /// <value>
        /// The end.
        /// </value>
        public DateTime End
        {
            get { return end; }
            set
            {
                if (end != value)
                {
                    end = value;
                    start = end - Duration;
                }
            }
        }

        /// <summary>
        /// Gets the duration.
        /// </summary>
        public TimeSpan Duration { get; private set; }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is fake.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is fake; otherwise, <c>false</c>.
        /// </value>
        public bool IsFake { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is support.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is support; otherwise, <c>false</c>.
        /// </value>
        public bool IsSupport { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is clearing.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is clearing; otherwise, <c>false</c>.
        /// </value>
        public bool IsClearing { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is noble.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is noble; otherwise, <c>false</c>.
        /// </value>
        public bool IsNoble { get; set; }

        /// <summary>
        /// Gets or sets the description.
        /// </summary>
        /// <value>
        /// The description.
        /// </value>
        public string Description { get; set; }

        /// <summary>
        /// Gets a value indicating whether this instance is old.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is old; otherwise, <c>false</c>.
        /// </value>
        public bool IsOld
        {
            get { return (Start - DateTime.Now < TimeSpan.Zero); }
        }

        /// <summary>
        /// Occurs when this instance is changed.
        /// </summary>
        public event EventHandler Changed;

        #endregion

        /// <summary>
        /// Raises the <see cref="Changed"/> event.
        /// </summary>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void OnChanged(EventArgs e)
        {
            if (Changed != null) Changed(this, e);
        }
    }
}